import { Upload, Button, Form, Select, Input, Steps, message, Space } from 'antd';
import { UploadOutlined, PlusOutlined, DeleteOutlined, PlayCircleOutlined } from '@ant-design/icons';
import { v4 as uuidv4 } from 'uuid';
import { processMerges, getArrHandleType, handleExcelTypeDict, handleExport } from '../../utils/excel';
import ExcelWorker from '@/utils/excel.worker?worker';
import './xlsx.less'

type CurrentData = {
  rawData: ExcelRow[];
  displayData: any[];
  columns: Array<{ title: string; dataIndex: string }>;
  merges: MergeInfo[];
}

interface IProps {
  onChangeData?: (data: CurrentData) => void;
  data?: CurrentData
}

const { Step } = Steps;

const App: React.FC<IProps> = ({ onChangeData }) => {
  const [form] = Form.useForm();
  const [steps, setSteps] = useState<ProcessStep[]>([]);
  // 同步步骤
  // const [stepRunning, setStepRunning] = useState<boolean>(false);
  const [uploadedData, setUploadedData] = useState<ExcelRow[][]>([]);
  const [currentData, setCurrentData] = useState<CurrentData>({ rawData: [], displayData: [], columns: [], merges: [] });
  // 修改规则(未完成)
  // const [modifyRules, setModifyRules] = useState<ModifyRule[]>([]);
  // 状态管理列映射(未完成)
  // const [fileMappings, setFileMappings] = useState<FileMappingConfig[]>([]);
  const workerRef = useRef<Worker>(null);

  // 初始化 Worker
  useEffect(() => {
    workerRef.current = new ExcelWorker();
    workerRef.current.onmessage = (e: MessageEvent<WorkerMessage>) => {
      const { type, data, merges, fileName, error, sendTime, receiveTime } = e.data;
      if (error) return message.error(error);
      const processEndTime = performance.now();
      console.log(`${type}性能统计`, sendTime, receiveTime, processEndTime)
      // setStepRunning(true)
      switch (type) {
        case "parse":
          setUploadedData((prev) => [...prev, data]); // 保存每个文件的数据
          setCurrentData((prev) => ({
            ...prev,
            rawData: [...prev.rawData, ...data],
            displayData: processMerges(
              [...prev.rawData, ...data],
              merges || []
            ),
            columns: Object.keys(data[0] || {}).map((key) => ({
              title: key,
              dataIndex: key,
            })),
            merges: merges || [],
          }));
          console.log(`文件 ${fileName} 解析成功`);
          break;

        case "merge": {
          setCurrentData((prev) => ({
            ...prev,
            rawData: data,
            displayData: processMerges(data, prev.merges),
          }));
          console.log("数据合并成功");
          break;
        }

        case "dedupe":
          setCurrentData((prev) => ({
            ...prev,
            rawData: data,
            displayData: processMerges(data, prev.merges),
          }));
          console.log("数据去重成功");
          break;

        case "filter":
          console.log(data);
          break;

        case "modify":
          setCurrentData((prev) => ({
            ...prev,
            rawData: data,
            displayData: processMerges(data, prev.merges),
          }));
          break;

        case "export":
          handleExport(data, fileName || '导出数据.xlsx');
          console.log("数据导出中...");
          break;
      }
      console.log(`${type}步骤执行完成`);
      // setStepRunning(false)
    };
    return () => workerRef.current?.terminate();
  }, []);

  useEffect(() =>{
    onChangeData?.(currentData)
  }, [currentData]);
  // 执行工作流
  const runWorkflow = async () => {
    const value = await form.validateFields();
    const processingData = currentData.rawData;

    for (const [index, step] of steps.entries()) {
      const stepPromise = new Promise((resolve, reject) => {
        const messageHandler = (e: MessageEvent<WorkerMessage>) => {
          if (e.data.type === step.method && !e.data.error) {
            workerRef.current?.removeEventListener("message", messageHandler);
            resolve(true);
          }
          if (e.data.error) {
            reject(e.data.error);
          }
        };
        workerRef.current?.addEventListener("message", messageHandler);
      });
      
      const sendTime = performance.now();

      // 收集所有任务，在woker同步执行，通过传递一个开始执行方法，在worker中执行流
      try {
        switch (step.method) {
          case "merge":
            workerRef.current?.postMessage({
              type: "merge",
              data: uploadedData, // 传递所有文件数据
              mergeField: step.params?.mergeField,
              sendTime,
            });
            break;

          case "dedupe":
            workerRef.current?.postMessage({
              type: "dedupe",
              data: processingData,
              dedupeField: step.params?.dedupeField,
              sendTime,
            });
            break;

          case "filter":
            console.log(processingData);
            break;

          case "export":
            workerRef.current?.postMessage({
              type: "export",
              data: processingData,
              fileName: value.steps[index].params.fileName,
              sendTime,
            });
            break;
        }
        // 等待操作完成（已优化为Worker 消息机制同步）
        await stepPromise;
      } catch (error) {
        message.error(`步骤 ${index + 1} 执行失败`);
        break;
      }
    }
  };

  // 修改规则,规则较多需要好好设计
  const ModifyRuleEditor = ({ ruleIndex }: { ruleIndex: number }) => (
    <Space>
      <Form.Item
        label="目标字段"
        name={["steps", "params", "modifyRules", ruleIndex, "field"]}
        rules={[{ required: true }]}
      >
        <Select
          options={currentData.columns.map((c) => {
            return { label: c.title, value: c.dataIndex };
          })}
        />
      </Form.Item>

      <Form.Item
        label="修改类型"
        name={["steps", "params", "modifyRules", ruleIndex, "type"]}
        rules={[{ required: true }]}
      >
        <Select
          options={[
            { label: "替换值", value: "replace" },
            { label: "计算公式", value: "calculate" },
            { label: "格式化", value: "format" },
          ]}
        />
      </Form.Item>

      {/* 动态参数配置 */}
      <Form.Item noStyle shouldUpdate={(prev, curr) => prev.type !== curr.type}>
        {({ getFieldValue }) => {
          const type = getFieldValue([
            "steps",
            "params",
            "modifyRules",
            ruleIndex,
            "type",
          ]);
          switch (type) {
            case "replace":
              return (
                <>
                  <Form.Item
                    label="原值"
                    name={[
                      "steps",
                      "params",
                      "modifyRules",
                      ruleIndex,
                      "config",
                      "oldValue",
                    ]}
                    rules={[{ required: true }]}
                  >
                    <Input placeholder="要替换的值" />
                  </Form.Item>
                  <Form.Item
                    label="新值"
                    name={[
                      "steps",
                      "params",
                      "modifyRules",
                      ruleIndex,
                      "config",
                      "newValue",
                    ]}
                    rules={[{ required: true }]}
                  >
                    <Input placeholder="替换后的值" />
                  </Form.Item>
                </>
              );
            case "calculate":
              return (
                <Form.Item
                  label="公式"
                  name={[
                    "steps",
                    "params",
                    "modifyRules",
                    ruleIndex,
                    "config",
                    "formula",
                  ]}
                  rules={[{ required: true }]}
                >
                  <Input placeholder="例如: value * 0.8" />
                </Form.Item>
              );
            case "format":
              return (
                <Form.Item
                  label="格式"
                  name={[
                    "steps",
                    "params",
                    "modifyRules",
                    ruleIndex,
                    "config",
                    "format",
                  ]}
                  rules={[{ required: true }]}
                >
                  <Select
                    options={[
                      { label: "货币格式", value: "currency" },
                      { label: "日期格式", value: "date" },
                    ]}
                  />
                </Form.Item>
              );
            default:
              return null;
          }
        }}
      </Form.Item>
    </Space>
  );

  return (
    <div style={{ padding: 24 }}>
      {/* 步骤配置区 */}
      <Form form={form}>
        <Steps current={steps.length} style={{ marginBottom: 24 }}>
          {steps.map((item, index) => (
            <Step key={item.id} title={`步骤 ${index + 1}`} />
          ))}
        </Steps>

        {steps.map((step, index) => (
          <div key={step.id} className="select-item-box">
            <Space align="start">
              <Form.Item
                label="处理方法"
                name={["steps", index, "method"]}
                rules={[{ required: true, message: "请选择处理方法" }]}
              >
                <Select
                  options={getArrHandleType()}
                  style={{ width: 200 }}
                  onChange={(value) => {
                    const newSteps = [...steps];
                    newSteps[index].method = value;
                    setSteps(newSteps);
                  }}
                />
              </Form.Item>

              {step.method === "merge" && (
                <Form.Item
                  label="合并字段"
                  name={["steps", index, "params", "mergeField"]}
                  rules={[{ required: true, message: "请选择合并字段" }]}
                >
                  <Select
                    options={currentData.columns.map((c) => ({
                      label: c.title,
                      value: c.dataIndex,
                    }))}
                    style={{ width: 200 }}
                  />
                </Form.Item>
              )}

              {step.method === "dedupe" && (
                <Form.Item
                  label="去重字段"
                  name={["steps", index, "params", "dedupeField"]}
                  rules={[{ required: true, message: "请选择去重字段" }]}
                >
                  <Select
                    options={currentData.columns.map((c) => ({
                      label: c.title,
                      value: c.dataIndex,
                    }))}
                    style={{ width: 200 }}
                  />
                </Form.Item>
              )}

              {step.method === "filter" && (
                <Form.Item
                  label="去重字段"
                  name={["steps", index, "params", "filterField"]}
                  rules={[{ required: true, message: "请选择筛选关键字段" }]}
                >
                  <Select
                    options={currentData.columns.map((c) => ({
                      label: c.title,
                      value: c.dataIndex,
                    }))}
                    style={{ width: 200 }}
                  />
                </Form.Item>
              )}

              {step.method === "modify" && (
                <Form.List name={["steps", index, "params", "modifyRules"]}>
                  {(fields, { add, remove }) => (
                    <div style={{ marginTop: 12 }}>
                      {fields.map((field, ruleIndex) => (
                        <div key={field.key} style={{ marginBottom: 12 }}>
                          <ModifyRuleEditor ruleIndex={ruleIndex} />
                          <Button onClick={() => remove(ruleIndex)} danger>
                            删除规则
                          </Button>
                        </div>
                      ))}
                      <Button
                        onClick={() => add({ field: "", type: "replace" })}
                      >
                        添加规则
                      </Button>
                    </div>
                  )}
                </Form.List>
              )}

              {step.method === "export" && (
                <Form.Item
                  label="文件重命名"
                  name={["steps", index, "params", "fileName"]}
                >
                  <Input
                    placeholder="例如：项目审计.xlsx"
                    style={{ width: 200 }}
                  />
                </Form.Item>
              )}

              <Button
                icon={<DeleteOutlined />}
                onClick={() => setSteps(steps.filter((_, i) => i !== index))}
                danger
              />
            </Space>
            <div className="step-explain">
              {handleExcelTypeDict[step.method]?.explain}
            </div>
          </div>
        ))}

        <Button
          type="dashed"
          onClick={() => setSteps([...steps, { method: "parse", params: {}, id: uuidv4() }])}
          icon={<PlusOutlined />}
        >
          添加步骤
        </Button>
      </Form>

      {/* 操作区 */}
      <Space style={{ marginTop: 24 }}>
        <Upload
          beforeUpload={(file) => {
            const reader = new FileReader();
            reader.onload = (e) => {
              workerRef.current?.postMessage({
                type: "parse",
                data: new Uint8Array(e.target?.result as ArrayBuffer),
                fileName: file.name,
              });
            };
            reader.readAsArrayBuffer(file);
            return false;
          }}
          showUploadList={false}
          multiple
        >
          <Button icon={<UploadOutlined />}>上传多个 Excel 文件</Button>
        </Upload>

        <Button
          type="primary"
          icon={<PlayCircleOutlined />}
          onClick={runWorkflow}
          disabled={steps.length === 0}
        >
          执行工作流
        </Button>
      </Space>
    </div>
  );
};

export default App;